#ifndef FDILINK_DATA_STRUCT_H_
#define FDILINK_DATA_STRUCT_H_

#include <iostream>
namespace FDILink
{

#define FRAME_HEAD 0xfc
#define FRAME_END 0xfd
#define TYPE_IMU 0x40
#define TYPE_AHRS 0x41
#define TYPE_INSGPS 0x42
#define TYPE_GEODETIC_POS 0x5c
#define TYPE_GROUND 0xf0

#define HEADER_LEN 0x07		// 帧头长度，固定值
#define IMU_LEN 0x38		  // 56
#define AHRS_LEN 0x30		  // 48
#define INSGPS_LEN 0x48		  // 80
#define GEODETIC_POS_LEN 0x20 // 32
#define PI 3.141592653589793
#define DEG_TO_RAD 0.017453292519943295

// 协议通用帧头
#pragma pack(1)
	struct fdilink_header
	{
		uint8_t header_start;	// 起始字节，帧头标志，一般固定值（例如0xAA）
		uint8_t data_type;		// 数据类型（区分IMU/AHRS/INS等）
		uint8_t data_size;		// 后续数据部分大小（不含帧头和尾）
		uint8_t serial_num;		// 帧序号，方便丢包检测
		uint8_t header_crc8;	// 帧头CRC8校验码
		uint8_t header_crc16_h; // 帧头CRC16高字节
		uint8_t header_crc16_l; // 帧头CRC16低字节
	};
#pragma pack()

// ###### 各类数据包定义 ######

// 惯导数据，包含陀螺仪、加速度计、磁力计等，长度56字节
#pragma pack(1)
	struct IMUData_Packet_t
	{
		float gyroscope_x;			// unit: rad/s
		float gyroscope_y;			// unit: rad/s
		float gyroscope_z;			// unit: rad/s
		float accelerometer_x;		// m/s^2
		float accelerometer_y;		// m/s^2
		float accelerometer_z;		// m/s^2
		float magnetometer_x;		// mG
		float magnetometer_y;		// mG
		float magnetometer_z;		// mG
		float imu_temperature;		// C
		float Pressure;				// Pa
		float pressure_temperature; // C
		int64_t Timestamp;			// us
	};
#pragma pack()

	// 姿态解算数据，含滚转、俯仰、航向角及四元数，长度48字节
	struct AHRSData_Packet_t
	{
		float RollSpeed;	// unit: rad/s
		float PitchSpeed;	// unit: rad/s
		float HeadingSpeed; // unit: rad/s
		float Roll;			// unit: rad
		float Pitch;		// unit: rad
		float Heading;		// unit: rad
		float Qw;			// w          //Quaternion
		float Qx;			// x
		float Qy;			// y
		float Qz;			// z
		int64_t Timestamp;	// unit: us
	};

// INS融合GPS数据，含速度、加速度、位置、气压等，长度72字节。
#pragma pack(1)
	struct INSGPSData_Packet_t
	{
		float BodyVelocity_X;
		float BodyVelocity_Y;
		float BodyVelocity_Z;
		float BodyAcceleration_X;
		float BodyAcceleration_Y;
		float BodyAcceleration_Z;
		float Location_North;
		float Location_East;
		float Location_Down;
		float Velocity_North;
		float Velocity_East;
		float Velocity_Down;
		float Acceleration_North;
		float Acceleration_East;
		float Acceleration_Down;
		float Pressure_Altitude;
		int64_t Timestamp;
	};
#pragma pack()

// 地理坐标数据，含经纬度、高度和定位精度，长度40字节。
#pragma pack(1)
	struct Geodetic_Position_Packet_t
	{
		double Latitude;
		double Longitude;
		double Height;
		float hAcc;
		float vAcc;
	};
#pragma pack()

// ##### 协议帧定义 #######

// for IMU=========================
#pragma pack(1)
	struct read_imu_struct
	{
		fdilink_header header; // 7
		union data
		{
			IMUData_Packet_t data_pack; // 56
			uint8_t data_buff[56];		// 56
		} data;
		uint8_t frame_end; // 1
	};

	struct read_imu_tmp
	{
		uint8_t frame_header[7];
		uint8_t read_msg[57];
	};

	union imu_frame_read
	{
		struct read_imu_struct frame;
		read_imu_tmp read_buf;
		uint8_t read_tmp[64];
	};
#pragma pack()
// for IMU------------------------

// for AHRS=========================
#pragma pack(1)
	struct read_ahrs_struct
	{
		fdilink_header header; // 7
		union data
		{
			AHRSData_Packet_t data_pack; // 48
			uint8_t data_buff[48];		 // 48
		} data;
		uint8_t frame_end; // 1
	};

	struct read_ahrs_tmp
	{
		uint8_t frame_header[7];
		uint8_t read_msg[49];
	};

	union ahrs_frame_read
	{
		struct read_ahrs_struct frame;
		read_ahrs_tmp read_buf;
		uint8_t read_tmp[56];
	};
#pragma pack()
// for AHRS------------------------

// for INSGPS=========================
#pragma pack(1)
	struct read_insgps_struct
	{
		fdilink_header header; // 7
		union data
		{
			INSGPSData_Packet_t data_pack; // 72
			uint8_t data_buff[72];		   // 72
		} data;
		uint8_t frame_end; // 1
	};

	struct read_insgps_tmp
	{
		uint8_t frame_header[7];
		uint8_t read_msg[73];
	};

	union insgps_frame_read
	{
		struct read_insgps_struct frame;
		read_insgps_tmp read_buf;
		uint8_t read_tmp[80];
	};
#pragma pack()
// for INSGPS------------------------

// for Geodetic_Position=========================
#pragma pack(1)
	struct read_Geodetic_Position_struct
	{
		fdilink_header header; // 7
		union data
		{
			Geodetic_Position_Packet_t data_pack; // 40
			uint8_t data_buff[32];				  // 40
		} data;
		uint8_t frame_end; // 1
	};

	struct read_Geodetic_Position_tmp
	{
		uint8_t frame_header[7];
		uint8_t read_msg[33];
	};

	union Geodetic_Position_frame_read
	{
		struct read_Geodetic_Position_struct frame;
		read_Geodetic_Position_tmp read_buf;
		uint8_t read_tmp[40];
	};

#pragma pack()

} // namespace FDILink

#endif // FDILINK_DATA_STRUCT_H_
